package com.sasken.pdb.views.renderers
{
	
	import com.sasken.pdb.controllers.IScheduleViewStatus;
	import com.sasken.pdb.controllers.ScheduleViewController;
	import com.sasken.pdb.controllers.events.GridItemEditEvent;
	import com.sasken.pdb.controllers.events.ScheduleSliderEvent;
	import com.sasken.pdb.models.data.IWorkload;
	import com.sasken.pdb.models.data.ScheduleItem;
	import com.sasken.pdb.views.components.GradientCanvas;
	import com.sasken.pdb.views.components.ScheduleBar;
	import com.sasken.pdb.views.components.ScheduleView;
	
	import flash.events.MouseEvent;
	
	import mx.controls.AdvancedDataGrid;
	import mx.core.ScrollPolicy;

	public class ScheduleItemRenderer extends CanvasItemRenderer
	{
		
		//Spacer - width of the columns under the column group
		private var _spacer:int = 0;
		    
		//To calculate the indentation for the gantt renderer based on days
		private var _spacePerDay:int = 0;
		
		private var parentGrid:AdvancedDataGrid;
		private var scheduleViewStatus:IScheduleViewStatus;
		
		private var currentEditItem:ScheduleBar;
		
		private var schedBars:Array;
		
		private static var HEIGHT_MARGIN:int = 4;
		
		private var _rendererMode:int;
		
		public function ScheduleItemRenderer()
		{
			super();
			schedBars = new Array();
			horizontalScrollPolicy = ScrollPolicy.OFF;
			verticalScrollPolicy = ScrollPolicy.OFF;
			_rendererMode = ScheduleViewController.RENDERER_MODE_INVALID;
		}
		
		private function renderYearItems(items:Array):void
		{
			// TODO merge items together
			// Generate one item for each Quarter. 
			// If values are the same, merge them.
			
			//var renderItems:Array = new Array();
			
			//var q1Item:ScheduleItem = new ScheduleItem();
			//var q2Item:ScheduleItem = new ScheduleItem();
			//var q3Item:ScheduleItem = new ScheduleItem();
			//var q4Item:ScheduleItem = new ScheduleItem();
			
			for(var i:int = 0; i < items.length; ++i)
			{
				var schedItem:Object = items[i];
				
				//trace(scheduleViewStatus.viewportStartDate,scheduleViewStatus.viewportEndDate);
				
				var startDate:Date = schedItem.startDate ? schedItem.endDate : new Date(0);
				var endDate:Date = schedItem.endDate ?  schedItem.endDate : new Date(0);
				
				// don't show items unless they appear in the viewport
				if (
					(startDate.getTime() >= scheduleViewStatus.viewportStartDate.getTime() && 
					 endDate.getTime() <= scheduleViewStatus.viewportEndDate.getTime()) || 
					
					(startDate.getTime() <= scheduleViewStatus.viewportEndDate.getTime() && 
					 endDate.getTime() >= scheduleViewStatus.viewportEndDate.getTime()) || 
					
					(startDate.getTime() >= scheduleViewStatus.viewportStartDate.getTime() && 
					 endDate.getTime() <= scheduleViewStatus.viewportEndDate.getTime())
				   )	
					
				{
					renderItem(schedItem as ScheduleItem);
				}
			}
		}
		
		
		private function renderItem(item:ScheduleItem):void
		{
			var schedBar:ScheduleBar = new ScheduleBar();			
			schedBar.visible = false;
			schedBars.push(schedBar);
			schedBar.height = parentGrid.rowHeight - HEIGHT_MARGIN;
			addChild(schedBar);
			
			schedBar.percentWidth = 100;
			schedBar.gradientCanvas.x = scheduleViewStatus.getX1PosForScheduleItem(item);
			schedBar.gradientCanvas.width = scheduleViewStatus.getX2PosForScheduleItem(item) - schedBar.gradientCanvas.x;
			schedBar.scheduleViewStatus = scheduleViewStatus;
			schedBar.scheduleItem = item;
			schedBar.gradientcolor = item.backgroundColor;
			
			schedBar.addEventListener(ScheduleSliderEvent.SLIDE_EVENT, onSlide);
			schedBar.gradientCanvas.addEventListener(MouseEvent.CLICK, onItemClick);
			
			
			
			schedBar.visible = true;
		}
		
		private function onSlide(e:ScheduleSliderEvent):void
		{
			var schedItem:ScheduleItem = e.oldScheduleItem;
			
			// TODO: 
			// check here if the new time conflicts with existing nodes. If not,
			// set new time to replace current one. If there is conflict, resolve it locally
			// and dispatch an event to schedule view controller so that it will redraw the 
			// row.
			schedItem.startDate = e.newScheduleItem.startDate;
			schedItem.endDate = e.newScheduleItem.endDate;
			schedItem.label = e.newScheduleItem.label;
			schedItem.load = e.newScheduleItem.load;

			/*			
			for(var i:int = 0; i < schedBars.length; ++i)
			{
				var bar:ScheduleBar = schedBars[i];
				bar.removeEventListener(MouseEvent.CLICK, onItemClick);
				bar.removeEventListener(ScheduleSliderEvent.SLIDE_EVENT, onSlide);
				removeChild(bar);
			}
			schedBars = [];
			*/
				
			dispatchEvent(new GridItemEditEvent(GridItemEditEvent.GRID_ROW_UPDATE, schedItem, true));

			// TODO  
			//  - never mind the speed (optimize later)
			//  - creation of new items by double clicking somewhere (default span/load 1wk/100%)
			//  	** clicking anywhere ok, even in middle of existing items
			//	- no merging of existing items needed yet -> future dev task
			//  - slider thumb positioning to edges of slider (take a look at doug mccune's implemenetation)
			
			//trace("slide");
			//trace(e.newScheduleItem);
			//trace(e.oldScheduleItem);
			
		}
	
		private function onItemClick(e:MouseEvent):void
		{
		
			if (scheduleViewStatus.editMode && e.currentTarget is GradientCanvas)
			{
				
				var schedBar:ScheduleBar = ScheduleBar(e.currentTarget.parent);

				schedBar.editMode = !schedBar.editMode;
										
				if (schedBar.editMode)
				{
					if (currentEditItem && 
						currentEditItem != schedBar && 
						currentEditItem.editMode)
					{
						currentEditItem.editMode = false;
					}
					currentEditItem = schedBar;
				}
				else
				{
					currentEditItem = null;
				}
			}
			dispatchEvent(new GridItemEditEvent(GridItemEditEvent.GRID_EDIT_EVENT, currentEditItem, true));
		}

	    //override data setter
		override public function set data(value:Object):void
		{
			if (!value) return;
			var i:int;
			var workload:Array;
			var schedItem:ScheduleItem;
			
			//var timer:int = getTimer();
			//trace("timer now: ", timer);
			//trace("setting data to ScheduleItemRenderer");
			
			if (!parentGrid)
			{
				parentGrid = AdvancedDataGrid(listData.owner);
				scheduleViewStatus = IScheduleViewStatus((parentGrid.parent.parent as ScheduleView).controller);
			}
			
			super.data = value;
			
			if (value is IWorkload)
			{
				workload = IWorkload(value).getWorkload(scheduleViewStatus.useCondensedSchedules);
			}
			else
			{
				return;
			}
			
			if (!workload) return;
			
			// check if data is the same as previously saved data.
			// if it is, don't flush children!
			var itemsChanged:Boolean = false;
			if (schedBars.length == workload.length)
			{
				
				for(i = 0; i < schedBars.length; ++i)
				{
					schedItem = schedBars[i].scheduleItem;
					var wlSchedItem:ScheduleItem = workload[i] as ScheduleItem;
					if (schedItem.id != wlSchedItem.id ||
						schedItem.startDate.getTime() != wlSchedItem.startDate.getTime() || 
						schedItem.endDate.getTime() != wlSchedItem.endDate.getTime() || 
						schedItem.load != wlSchedItem.load)
					{
						itemsChanged = true;
						break;
					}
				}
			}
			else
			{
				itemsChanged = true;
			}
			
			
			
			
			//Remove any existing children, done for cleaning up and redrawing while scrolling
			//Heavy on performance, but would do for the time being :(
			//TODO: Prune this!
			if (!itemsChanged && _rendererMode == scheduleViewStatus.rendererMode)
			{
				return;
			}
			
			this.removeAllChildren();
			schedBars = [];
			_rendererMode = scheduleViewStatus.rendererMode;
			
		    if (scheduleViewStatus.rendererMode == ScheduleViewController.RENDERER_MODE_YEAR)
			{				
				renderYearItems(workload);				
			}
			else if (scheduleViewStatus.rendererMode == ScheduleViewController.RENDERER_MODE_QUARTER)
			{
				for(i=0; i < workload.length; ++i)
				{
					schedItem = workload[i];
					
					if (!(schedItem.startDate.getFullYear() > scheduleViewStatus.currentYear ||
						 schedItem.endDate.getFullYear() < scheduleViewStatus.currentYear))
					{
						renderItem(schedItem);
					}		
					
				}					
			}
			
			//trace("timer at end:", getTimer(), "diff: ", getTimer() - timer);
		}	
		
		
	}
}